package api

import (
	reponse "GinTest_api/global/response"
	"GinTest_api/middlewares"
	"GinTest_api/models"
	"GinTest_api/proto"
	"context"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/grpc/status"
	"net/http"
	"strconv"
	"time"
)

// 服务端内部错误
func HandleGrpcErrorToHttp(err error, c *gin.Context) {
	//将grpc的code转换成http的状态码
	if err != nil {
		if e, ok := status.FromError(err); ok {
			switch e.Code() {
			case codes.NotFound:
				c.JSON(http.StatusNotFound, gin.H{
					"msg": e.Message(),
				})
			case codes.Internal:
				c.JSON(http.StatusInternalServerError, gin.H{
					"msg:": "内部错误",
				})
			case codes.InvalidArgument:
				c.JSON(http.StatusBadRequest, gin.H{
					"msg": "参数错误",
				})
			case codes.Unavailable:
				c.JSON(http.StatusInternalServerError, gin.H{
					"msg": "用户服务不可用",
				})
			default:
				c.JSON(http.StatusInternalServerError, gin.H{
					"msg": e.Code(),
				})
			}
			return
		}
	}
}

/*
*

		@Author fuyx
	 	@Text 用户登录
		@Request proto
	    @Return data
*/
func UserLogin(ctx *gin.Context) {
	zap.S().Debug("用户登录")
	//token验证
	//tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJRCI6MSwiTmlja05hbWUiOiIxMzY5MTE2Mzc4MCIsIkF1dGhvcml0eUlkIjoxLCJleHAiOjE3MDA4MDkwMjIsImlzcyI6ImZ1eXgiLCJuYmYiOjE2OTgyMTcwMjJ9.n0zSevMoxpKq6e1Ww0iOlNikYrU36iSw8M5DKGDXKrA"
	//j := middlewares.NewJWT()
	//result, err := j.ParseToken(tokenString) //token, err := jwt.ParseWithClaims(tokenString, &models.CustomClaims{}, func(token *jwt.Token) (i interface{}, e error) {
	//ctx.JSON(200, gin.H{
	//	"data": result,
	//})
	//	return j.SigningKey, nil
	//})
	//
	//if token != nil {
	//	if claims, ok := token.Claims.(*models.CustomClaims); ok && token.Valid {
	//		ctx.JSON(200, gin.H{
	//			"data": claims,
	//		})
	//	}
	//}

	ip := "0.0.0.0"
	port := 50051
	mobile := ctx.DefaultQuery("mobile", "13691163780")
	password := ctx.DefaultQuery("Password", "123456")
	userClient, err := grpc.Dial(fmt.Sprintf("%s:%d", ip, port), grpc.WithTransportCredentials(insecure.NewCredentials()))
	userSrvClient := proto.NewUserClient(userClient)
	data, err := userSrvClient.UserLogin(context.Background(), &proto.LoginRequest{
		Mobile:   mobile,
		Password: password,
	})
	if err != nil {
		HandleGrpcErrorToHttp(err, ctx)
		return
	}
	j := middlewares.NewJWT()

	claims := models.CustomClaims{
		ID:          uint(data.Id),
		NickName:    mobile,
		AuthorityId: uint(data.Role),
		StandardClaims: jwt.StandardClaims{
			NotBefore: time.Now().Unix(),               //签名的生效时间
			ExpiresAt: time.Now().Unix() + 60*60*24*30, //30天过期
			Issuer:    "fuyx",
		},
	}
	token, err := j.CreateToken(claims)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg": "生成token失败",
		})
		return
	}

	ctx.JSON(200, gin.H{
		"msg": token,
		//"data": data,
	})

}

func GetUserList(ctx *gin.Context) {

	zap.S().Debug("获取用户列表")
	//grpc连接
	ip := "0.0.0.0"
	port := 50051

	//生成grpc的client并调用接口
	pn := ctx.DefaultQuery("pn", "0")
	pnInt, _ := strconv.Atoi(pn)
	pSize := ctx.DefaultQuery("psize", "2000")
	pSizeInt, _ := strconv.Atoi(pSize)
	//建立连接
	userClent, err := grpc.Dial(fmt.Sprintf("%s:%d", ip, port), grpc.WithTransportCredentials(insecure.NewCredentials()))
	userSrvClient := proto.NewUserClient(userClent)
	data, err := userSrvClient.GetUserList(context.Background(), &proto.PageInfo{
		Pn:    uint32(pnInt),
		PSize: uint32(pSizeInt),
	})
	if err != nil {
		zap.S().Errorw("[GetUserList] 查询 【用户列表】失败")
		HandleGrpcErrorToHttp(err, ctx)
		return
	}
	reMap := gin.H{
		"total": data.Total,
	}
	result := make([]interface{}, 0)
	for _, value := range data.Data {
		user := reponse.UserResponse{
			Id:       value.Id,
			NickName: value.NickName,
			Birthday: reponse.JsonTime(time.Unix(int64(value.BirthDay), 0)),
			Gender:   value.Gender,
			Mobile:   value.Mobile,
		}
		result = append(result, user)
	}

	reMap["data"] = result
	ctx.JSON(http.StatusOK, reMap)
}
